import React, {useEffect, useRef, useState } from 'react';
import styled from'styled-components';
import style from '../../assets/global-style';
import { prefixStyle } from './../../api/utils';

const ProgressBarWrapper = styled.div`
  height: 30px;
  .bar-inner{
    position: relative;
    top: 13px;
    height: 4px;
    background: rgba(0, 0, 0, .3);
    .progress{
      position: absolute;
      height: 100%;
      background: ${style["theme-color"]};
    }
    .progress-btn-wrapper{
      position: absolute;
      left: -8px;
      top: -13px;
      width: 30px;
      height: 30px;
      .progress-btn{
        position: relative;
        top: 7px;
        left: 7px;
        box-sizing: border-box;
        width: 16px;
        height: 16px;
        border: 3px solid ${style["border-color"]};
        border-radius: 50%;
        background: ${style["theme-color"]};
      }
    }
  }
`;

/*
进度条组件作为播放器的一部分,我们思考一下将它被拆分出去后的功能,
一方面是要响应用户的拖动或点击动作,让进度条得以长度变化,
另一方面是要执行播放器组件传递过来的进度改变时需要的回调。
*/
function ProgressBar (props) {
  const progressBar = useRef ();
  const progress = useRef ();
  const progressBtn = useRef ();
  const [touch, setTouch] = useState ({});

  const progressBtnWidth = 16;

  const { percent } = props;

  const { percentChange } = props;

  const _changePercent = () => {
    const barWidth = progressBar.current.clientWidth - progressBtnWidth;
    const curPercent = progress.current.clientWidth / barWidth;// 新的进度计算
    percentChange(curPercent);// 把新的进度传给回调函数并执行
  };

  // 处理进度条的偏移
  const _offset = (offsetWidth) => {
    progress.current.style.width = `${offsetWidth}px`;
    progressBtn.current.style.transform = `translate3d(${offsetWidth}px, 0, 0)`;
  };

  const progressTouchStart = (e) => {
    const startTouch = {};
    startTouch.initiated = true;//initial 为 true 表示滑动动作开始了
    startTouch.startX = e.touches[0].pageX;// 滑动开始时横向坐标
    startTouch.left = progress.current.clientWidth;// 当前 progress 长度
    setTouch(startTouch);
  };

  const progressTouchMove = (e) => {
    if(!touch.initiated) return;
    //滑动距离
    const deltaX = e.touches[0].pageX - touch.startX;
    const barWidth = progressBar.current.clientWidth - progressBtnWidth;
    const offsetWidth = Math.min(Math.max(0, touch.left + deltaX), barWidth);
    _offset(offsetWidth); //offset只会影响进度条样式, 但并不真的会影响歌曲播放的进度, 下面的_changePercent才会
  };

  const progressTouchEnd = (e) => {
    const endTouch = JSON.parse(JSON.stringify(touch));
    endTouch.initiated = false;
    setTouch(endTouch);
    _changePercent();
  };

  const progressClick = (e) => {
    const rect = progressBar.current.getBoundingClientRect ();
    const offsetWidth = e.pageX - rect.left;
    _offset (offsetWidth);
    _changePercent();
  };

  //监听percent
  useEffect(() => {
    if(percent >= 0 && percent <= 1 && !touch.initiated/*拖拽bar时的样式变化走的不是这里的逻辑 而是_offset 因为拖拽需要主动改变歌曲的播放进度 而这里只是根据歌曲进度被动的显示进度条*/) {
      const barWidth = progressBar.current.clientWidth - progressBtnWidth;
      const offsetWidth = percent * barWidth;
      progress.current.style.width = `${offsetWidth}px`;
      progressBtn.current.style['transform'] = `translate3d(${offsetWidth}px, 0, 0)`;
    }
    // eslint-disable-next-line
  }, [percent]);

  return (
    <ProgressBarWrapper>
      <div className="bar-inner" ref={progressBar}  onClick={progressClick}>
        <div className="progress" ref={progress}></div>
        <div className="progress-btn-wrapper" ref={progressBtn}
             onTouchStart={progressTouchStart}
             onTouchMove={progressTouchMove}
             onTouchEnd={progressTouchEnd}
        >
          <div className="progress-btn"></div>
        </div>
      </div>
    </ProgressBarWrapper>
  )
}

export default ProgressBar
